package cn.jja8.networkTransmission;


import cn.jja8.networkTransmission.tool.ByteSegmentation;
import cn.jja8.networkTransmission.tool.ByteTool;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 一个通道类，代表一个通道。并且提供在通道通讯的方法，也是一套简单的通讯协议
 * */
public class GitPassageway implements Passageway{
    DataClient b连接;
    String b名字;
    long get超时时时间;
    public String get名字() {
        return b名字;
    }
    public DataClient get连接() {
        return b连接;
    }

    /**
     * 构造一个通道
     * @param 名字 通道名字
     * @param get超时时间 毫秒，当get请求超过时间不回复就作废。
     */
    GitPassageway(DataClient 连接, String 名字, long get超时时间) {
        this.get超时时时间 = get超时时间;
        this.b连接 = 连接;
        this.b名字 = 名字;
        注册();
    }
    /**
     * 重新设置成新的连接，如果之前的连接已经失效可以调用此方法
     * */
    public void set连接(DataClient b连接){
        this.b连接 = b连接;
        注册();
    }
    private void 注册(){
        b连接.注册数据接收器(b名字+"_git",this::收到get请求);
        b连接.注册数据接收器(b名字+"_gitReturn",this::收到get请求返回);
    }
    long v上次处理时间 = 0;
    private void 处理超时() {
        if (v上次处理时间+get超时时时间>System.currentTimeMillis()){
            System.out.println("处理超时的请求");
            v上次处理时间 = System.currentTimeMillis();
            get请求处理map2 = get请求处理map1;
            get请求处理map1 = new HashMap<>();
        }
    }
    Map<Integer,GitReturn> get请求处理map2 = new HashMap<>();
    Map<Integer,GitReturn> get请求处理map1 = new HashMap<>();
    int get请求编号 = 0;
    /**
     * get请求被回复时的处理类
     * */
    public interface GitReturn{
        void 回复(byte[] b数据);
    }
    /**
     * 发送get请求
     * */
    public void 发送get请求(byte[] 数据,GitReturn get请求处理) throws IOException {
        get请求编号++;
        get请求处理map1.put(get请求编号,get请求处理);
        /*
        * 数据发送规则(编号,数据)
        * */
        b连接.发送数据(b名字+"_git", ByteSegmentation.合成(ByteTool.IntToByte(get请求编号),数据));
    }
    /**
     * get请求接收器
     * */
    public interface GitReceive{
        void 新Git请求(byte[] b数据, GitRequestReturn b数据返器, GitPassageway b通道);
    }
    /**
     * get请求的数据返回器
     * */
    public static class GitRequestReturn{
        GitPassageway passageway;
        byte[] b编号;
        public GitRequestReturn(byte[] 编号, GitPassageway passageway) {
            this.b编号 = 编号;
            this.passageway = passageway;
        }
        public void 返回数据(byte[] b数据) throws IOException {
            passageway.b连接.发送数据(passageway.b名字+"_gitReturn",ByteSegmentation.合成(b编号,b数据));
        }

        public GitPassageway get通道() {
            return passageway;
        }
    }
    private GitReceive gitReceive;
    /**
     * 当收到get请求后处理git请求
     * */
    private void 收到get请求(byte[] 数据, DataClient dataClient) {
        if (gitReceive == null) {
            return;
        }
        ByteSegmentation.Byte2 b拆分 = ByteSegmentation.拆分(数据);
        gitReceive.新Git请求(b拆分.b2,new GitRequestReturn(b拆分.b1,this),this);
        处理超时();
    }
    private void 收到get请求返回(byte[] bytes, DataClient dataClient) {
        ByteSegmentation.Byte2 拆分 = ByteSegmentation.拆分(bytes);
        int b编号 = ByteTool.ByteToInt(拆分.b1);
        GitReturn b返回执行器 = get请求处理map1.remove(b编号);
        if (b返回执行器 == null) {
            b返回执行器 = get请求处理map2.remove(b编号);
        }
        if (b返回执行器!=null){
            b返回执行器.回复(拆分.b2);
        }else {
            System.out.println("远程发来一个错误的返回，这可能是bug！！！");
        }

    }
    /**
     * 设置Git请求接收器
     * */
    public void setGit请求接收器(GitReceive Git请求接收器){
        gitReceive = Git请求接收器;
    }
}
